@file:Suppress("UNCHECKED_CAST", "CanBeParameter", "JoinDeclarationAndAssignment")

package com.virtualightning.mvvm.impl.adapter

import android.os.Bundle
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IntDef
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.RecyclerView
import com.virtualightning.mvvm.R
import com.virtualightning.mvvm.extensions.forEach
import com.virtualightning.mvvm.tools.SyncCode
import com.virtualightning.mvvm.tools.TinyLifecycle
import com.virtualightning.mvvm.widget.SwitchView
import java.lang.ref.WeakReference

/**
 *  Anchor : Create by CimZzz
 *  Time : 2021/1/26 10:31:07
 *  万能数据适配器
 *
 *  Version 2:
 *  使用 [IUniverseAdapterViewModel] 来将请求部分直接传递到 ViewModel 执行
 */
@Suppress(
	"ConvertSecondaryConstructorToPrimary", "MemberVisibilityCanBePrivate",
	"RemoveExplicitTypeArguments", "unused"
)
class UniverseAdapter : RecyclerView.Adapter<UniverseAdapter.BaseViewHolder<*>> {
	companion object {
		/**
		 * 全局 ItemType 表
		 */
		private val itemTypeMap = HashMap<Class<*>, DataMatchCase<*>>()

		/**
		 * 全局 Item 自增 Code
		 */
		private val itemTypeSyncCode = SyncCode()

		/**
		 * 注册新的 ViewHolder
		 * @param factory IViewHolderFactory<*, *> ViewHolder 工厂
		 * @param directViewHolderCls Class<*>? 对应的 View Holder 类
		 * @param onlyTry Boolean 尝试注册，如果 true 则重复注册不会抛出异常
		 */
		fun registerViewHolder(
			factory: IViewHolderFactory<*, *>,
			directViewHolderCls: Class<*>? = null,
			onlyTry: Boolean = true
		) {
			val viewHolderCls = directViewHolderCls ?: factory.getViewHolderCls()
			if (itemTypeMap.containsKey(viewHolderCls)) {
				if (!onlyTry) {
					throw RuntimeException("重复注册: $viewHolderCls")
				}
				return
			}

			val newType = itemTypeSyncCode.nextCode()
			itemTypeMap[viewHolderCls] = DataMatchCase(newType, factory)
		}

		/**
		 * 获取 ViewHolder 的全局 ItemType 类型
		 * @param cls Class<T> 数据类型
		 * @return DataMatchCase<*> 数据匹配对象
		 */
		internal fun <T : BaseViewHolder<*>> getViewHolderItemType(cls: Class<T>): DataMatchCase<*> {
			return itemTypeMap[cls] ?: throw RuntimeException("必须先注册 $cls")
		}

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/27 3:05 下午 by CimZzz
		// 以下内容为:
		// 底部状态定义
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 底部处于未加载状态
		 */
		private const val BottomNone = 0x0

		/**
		 * 底部处于加载状态
		 */
		private const val BottomLoading = 0x1

		/**
		 * 底部处于加载失败状态
		 */
		private const val BottomError = 0x2

		/**
		 * 底部处于加载完成状态
		 */
		private const val BottomOver = 0x4

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/27 3:05 下午 by CimZzz
		// 以下内容为:
		// 滑动状态定义
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 快速滑动中状态
		 */
		const val ScrollStateFast = 0x0

		/**
		 * 慢速滑动中状态
		 */
		const val ScrollStateSlow = 0x1

		/**
		 * 静止滑动状态
		 */
		const val ScrollStateIdle = 0x2

		/**
		 * 滑动状态限制注解
		 */
		@IntDef(ScrollStateIdle, ScrollStateSlow, ScrollStateFast)
		@Target(AnnotationTarget.VALUE_PARAMETER)
		@Retention(AnnotationRetention.SOURCE)
		annotation class ScrollState
	}

	/**
	 * 实际数据数据列表
	 */
	private val dataList: ArrayList<DataWrapper<*>> by lazy { ArrayList<DataWrapper<*>>() }

	/**
	 * 数据匹配表
	 * 用来决定，某个数据类型对应某一种 ViewHolder
	 */
	private var dataMatcherMap: HashMap<Class<*>, DataMatchCase<*>>? = null

	/**
	 * 延迟绑定数据匹配表
	 * 用来决定，某个数据类型对应某一种 ViewHolder
	 */
	private var multiDataMatcherMap: HashMap<Class<*>, ArrayList<MultiDataMatchCase<*>>>? = null

	/**
	 * 类型匹配表
	 * Adapter 内部 ItemType 映射表
	 * 通过数据匹配表解析，最终会形成 ItemType 映射表
	 */
	private val itemTypeMap: SparseArray<DataMatchCase<*>> by lazy { SparseArray<DataMatchCase<*>>() }

	/**
	 * 适配器配置数据
	 */
	private val options: Options
	private fun getOptions() = options

	/**
	 * 适配器键值
	 */
	private var adapterKey: Any? = null

	/**
	 * 适配器 ViewModel
	 */
	private var adapterViewModel: IUniverseAdapterViewModel? = null

	/**
	 * 当前支持的底部状态
	 * 根据适配器配置数据 [Options] 中存在何种底部布局决定，由 [BottomLoading]、[BottomError]、[BottomOver] 几种状态取并集
	 */
	private var allowBottomState: Int = 0x0

	/**
	 * 当前的底部状态
	 */
	private var currentBottomState: Int =
		BottomNone
	private var bottomStateWrapper: DataWrapper<Int> = DataWrapper(currentBottomState, 0)

	/**
	 * 判断是否处于正在加载中的状态
	 */
	private var isLoadingNow: Boolean = false

	/**
	 * 数据同步码
	 * 考虑各种场景，可能会存在加载下一页和刷新的数据同时到来的情况:
	 * 如果将两份数据同时接受，则会导致页码错乱的问题，所以在每次刷新之后，都会刷新数据同步码，
	 * 旧同步码的数据将会被忽略
	 */
	private val dataSyncCode = SyncCode()

	/**
	 * 适配器数据缓存池
	 * 适配器可以内部缓存一些数据供 ViewHolder 使用，这部分数据不会随着数据刷新而小时
	 */
	private val adapterCache: HashMap<String, Any> = HashMap()

	/**
	 * 适配器临时数据缓存池
	 * 在每次刷新时都会清空内部数据
	 */
	private var adapterTempCache: HashMap<String, Any>? = null

	/**
	 * 当前附着的 Recycler View
	 */
	private var attachedRecyclerView: RecyclerView? = null

	/**
	 * 上一次请求时保存的 Bundle 数据
	 * 考虑到某些数据加载请求会有一些数据伴随着请求不同而变化（比如页码），
	 * 可以通过数据 Bundle 来保存本次请求的变化数据，在下一次请求时使用
	 */
	private var lastRequestBundle: Bundle? = null

	/**
	 * 外界状态集合，目前包括:
	 * 1. Adapter 滑动状态
	 */
	private val outerState: OuterState by lazy { OuterState() }

	/**
	 * ViewHolder 帮助类
	 * ViewHolder 的核心类，是 ViewHolder 和 Adapter 以及外界沟通的桥梁
	 */
	private val viewHolderHelper: ViewHolderHelper by lazy { ViewHolderHelper() }

	/**
	 * RecyclerView 滑动监听器
	 * 监听 RecyclerView 滑动，根据配置的适配器滑动策略 [Options.adapterScrollStrategy] 来决定当前的滑动状态
	 *
	 * ** 只有配置了 [Options.adapterScrollStrategy] 才可以变更滑动状态，否则状态只为 [ScrollStateIdle]
	 * 或者 [ScrollStateFast] 两种
	 */
	private val onScrollListener: RecyclerView.OnScrollListener by lazy {
		object : RecyclerView.OnScrollListener() {
			override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
				val afterState = getOptions().adapterScrollStrategy?.onScrolled(dx, dy) ?: return
				viewHolderHelper.changeScrollState(afterState)
			}

			override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
				val afterState =
					getOptions().adapterScrollStrategy?.onScrollState(newState) ?: run {
						when (newState) {
							RecyclerView.SCROLL_STATE_IDLE -> {
								// RecyclerView 静止
								viewHolderHelper.changeScrollState(ScrollStateIdle)
							}
							else -> {
								viewHolderHelper.changeScrollState(ScrollStateFast)
							}
						}
						return
					}
				viewHolderHelper.changeScrollState(afterState)
			}
		}
	}

	/**
	 * 数据变化表
	 * 当调用 [notifyDataChanged] 有参方法时，会将数据暂存到该表中，直到所有
	 */
	private var dataChangedMap: DataChangedCacheMap = DataChangedCacheMap()


	/**
	 * 构造方法，需要提供 Options 进行初始化
	 * @param options Options
	 * @constructor
	 */
	constructor(options: Options) {
		this.options = options
		if (options.bottomLoadingLayoutId != null) {
			allowBottomState = allowBottomState or BottomLoading
		}
		if (options.bottomErrorLayoutId != null) {
			allowBottomState = allowBottomState or BottomError
		}
		if (options.bottomOverLayoutId != null) {
			allowBottomState = allowBottomState or BottomOver
		}

		// 遍历 DataMatchSet, 进行 ViewHolder 匹配
		options.dataMatcherSet.forEach {
			when (it) {
				is DataMatcher<*> -> {
					val case = getViewHolderItemType(it.viewHolderCls)
					if (dataMatcherMap == null) {
						dataMatcherMap = HashMap()
					}
					dataMatcherMap?.put(it.dataCls, case)
					itemTypeMap.put(case.itemType, case)
				}
				is InheritDataMatcher<*> -> {
					val case = getViewHolderItemType(it.viewHolderCls)
					if (dataMatcherMap == null) {
						dataMatcherMap = HashMap()
					}
					dataMatcherMap?.put(it.dataCls, case)
					itemTypeMap.put(case.itemType, case)
				}
				is ExtendDataMatcher<*> -> {
					val case = getViewHolderItemType(it.viewHolderCls)
					if (multiDataMatcherMap == null) {
						multiDataMatcherMap = HashMap()
					}
					var list = multiDataMatcherMap?.get(it.dataCls)
					if (list == null) {
						list = ArrayList()
						multiDataMatcherMap?.put(it.dataCls, list)
					}
					list.add(it.generateMultiDataMatchCase(case.itemType, case.viewHolderFactory))
					itemTypeMap.put(case.itemType, case)
				}
			}
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/1/26 上午11:15 by CimZzz
	// 以下内容为:
	// Adapter 回调方法
	///////////////////////////////////////////////////////////////////////////

	override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
		val layoutInflater = LayoutInflater.from(parent.context)
		if (viewType == 0) {
			val switchView: SwitchView =
				layoutInflater.inflate(R.layout.adapter_switchable, parent, false) as SwitchView
			options.bottomLoadingLayoutId?.let {
				switchView.addGenerator(it)
			}
			options.bottomOverLayoutId?.let {
				switchView.addGenerator(it)
			}
			options.bottomErrorLayoutId?.let {
				switchView.addGenerator(it) Generator@{ genView ->
					val clickId = options.bottomErrorClickLayoutId
					if (clickId != null) {
						val clickView = genView.findViewById<View>(clickId)
						if (clickView != null) {
							clickView.setOnClickListener {
								requestReload()
							}
							return@Generator
						}
					}

					genView.setOnClickListener {
						requestReload()
					}
				}
			}
			val viewHolder = BottomViewHolder(switchView, options)
			viewHolder.helper = WeakReference(viewHolderHelper)
			viewHolder.init()
			return viewHolder
		}
		val viewHolder =
			itemTypeMap.get(viewType).viewHolderFactory.generatorViewHolder(layoutInflater, parent)
		viewHolder.helper = WeakReference(viewHolderHelper)
		viewHolder.init()
		return viewHolder
	}

	override fun getItemCount(): Int {
		if (dataList.size == 0) {
			return 0
		}
		return dataList.size + checkBottomView()
	}

	override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
		if (checkIsBottomView(position)) {
			bottomStateWrapper.data = currentBottomState
			(holder as BottomViewHolder).bindData(bottomStateWrapper, viewHolderHelper)
		} else {
			val data = dataList[position]
			holder.bindData(data, viewHolderHelper)
		}

		if (!isLoadingNow && currentBottomState == BottomLoading) {
			// 加载策略
			options.adapterLoadStrategy?.onLoadPosition(position, dataList.size, this)
		}
	}

	override fun getItemViewType(position: Int): Int {
		if (checkIsBottomView(position)) {
			return 0
		}

		val data = dataList[position].data
		val cls = data!!::class.java

		// 先检查 MultiMap
		if (multiDataMatcherMap != null) {
			val list = multiDataMatcherMap?.get(cls)
			if (list != null) {
				for (dataMatcher in list) {
					if (dataMatcher.isMatch(data)) {
						return dataMatcher.itemType
					}
				}
			}
		}

		/// 再检查 DataMap
		if (dataMatcherMap != null) {
			val matchCase = dataMatcherMap?.get(cls)
			if (matchCase != null) {
				return matchCase.itemType
			}
		}

		return 0
	}

	override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
		attachedRecyclerView = recyclerView
		recyclerView.addOnScrollListener(onScrollListener)
	}

	override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
		attachedRecyclerView = null
		recyclerView.removeOnScrollListener(onScrollListener)
	}

	override fun onViewAttachedToWindow(holder: BaseViewHolder<*>) {
		super.onViewAttachedToWindow(holder)
		holder.helper = WeakReference(viewHolderHelper)
		holder.attach()
	}

	override fun onViewDetachedFromWindow(holder: BaseViewHolder<*>) {
		super.onViewDetachedFromWindow(holder)
		holder.helper = null
		holder.detach()
	}

	override fun onViewRecycled(holder: BaseViewHolder<*>) {
		super.onViewRecycled(holder)
		holder.recycled()
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/28 7:28 下午 by CimZzz
	// 以下内容为:
	// IUniverseAdapterViewModel 操作方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 贴附到指定 ViewModel 上
	 * @param adapterKey Any 适配器键值
	 * @param viewModel IUniverseAdapterViewModel ViewModel
	 */
	fun attachViewModel(adapterKey: Any, viewModel: IUniverseAdapterViewModel) {
		if (viewModel == this.adapterViewModel) {
			return
		}
		detachViewModel()
		this.adapterKey = adapterKey
		this.adapterViewModel = viewModel
		viewModel.onAdapterAttach(adapterKey, this)
	}

	/**
	 * 从已绑定的 ViewModel 上分离
	 */
	fun detachViewModel() {
		val adapterKey = this.adapterKey ?: return
		this.adapterViewModel?.onAdapterDetach(adapterKey, this)
		this.adapterKey = null
		this.adapterViewModel = null
		// 分离后更新数据同步码
		this.dataSyncCode.nextCode()
		return
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/28 3:35 下午 by CimZzz
	// 以下内容为:
	// 内部使用方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 检查当前是否存在底部 View
	 * @return Int 如果存在返回 1, 不存在返回 0
	 */
	private fun checkBottomView(): Int {
		return if (currentBottomState and allowBottomState != 0)
			1
		else 0
	}

	/**
	 * 切换底部状态并尝试去通知更新
	 * @param afterState Int 更新后的状态
	 */
	private fun changeBottomStateAndNotify(afterState: Int) {
		if (currentBottomState == afterState) {
			return
		}
		val beforeExist = checkBottomView() == 1
		currentBottomState = afterState
		val afterExist = checkBottomView() == 1
		if (beforeExist && afterExist) {
			notifyItemChanged(itemCount - 1)
		} else if (beforeExist) {
			notifyItemRemoved(itemCount - 1)
		} else if (afterExist) {
			notifyItemInserted(itemCount - 1)
		}
		// 其他情况表示均不存在
	}

	/**
	 * 检查是否为底部状态 View
	 * @param position Int 位置
	 * @return Boolean 判断当前是否为底部 View
	 */
	private fun checkIsBottomView(position: Int): Boolean {
		// 当存在 BottomView 时，实际数据长度为 dataList.size + 1，所以只需要判断
		// 当前下标是否等于 dataList.size 即可
		return position != 0 && position == dataList.size
	}

	/**
	 * 过滤当前数据列表
	 * @param dataList List<Any> 数据列表
	 * @return List<DataWrapper<*>> 过滤后的数据列表
	 */
	private fun filterDataList(dataList: List<Any>): List<DataWrapper<*>> {
		return dataList.filter { filterData(it) }
			.map { DataWrapper(it, dataChangedMap.getCurrentCode()) }
	}

	/**
	 * 过滤数据
	 * @param data Any 数据
	 * @return Boolean 如果是允许的数据，返回 true
	 */
	private fun filterData(data: Any): Boolean {
		val cls = data::class.java
		if (dataMatcherMap?.containsKey(cls) == true) {
			return true
		}

		val multiList = multiDataMatcherMap?.get(cls)
		if (multiList == null || multiList.isEmpty()) {
			return false
		}

		for (dataMatcher in multiList) {
			if (dataMatcher.isMatch(data)) {
				return true
			}
		}

		return false
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/1/26 下午3:16 by CimZzz
	// 以下内容为:
	// 数据请求方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 请求初始化加载
	 *
	 * 分为两种情况，立即刷新和静默刷新
	 * - 立即刷新，重置列表状态，更新数据同步码
	 * - 静默刷新，不重置列表状态，使用当前数据同步码，更新完成后重置列表状态、更新数据同步码
	 *
	 * @param isSilence Boolean 表示是否为静默状态
	 * @return InitAdapterProxy 初始化适配器调用代理
	 */
	fun requestInit(isSilence: Boolean): InitAdapterProxy {
		if (!isSilence) {
			resetDataList(null, null)
		}

		val proxy = InitAdapterProxy(
			this,
			if (isSilence) dataSyncCode.currentCode() else dataSyncCode.nextCode(),
			dataSyncCode,
			isSilence,
			lastRequestBundle
		)

		val adapterKey = this.adapterKey
		val viewModel = this.adapterViewModel
		if (adapterKey != null && viewModel != null) {
			viewModel.requestAdapterInit(adapterKey, proxy)
		}

		return proxy
	}

	/**
	 * 请求加载更多
	 * 首次调用时会将 isLoadingNow 置为 true，防止多次重复调用
	 * 直到调用 loadCompleted / resetDataList 才会将 isLoadingMore置为 false
	 *
	 * 调用时，会生成一个 [LoadMoreAdapterProxy] 对象，通过 [IAdapterCallback.onAdapterLoadMore] 方法
	 * 进行回调
	 *
	 */
	fun requestLoadMore() {
		if (isLoadingNow) {
			return
		}
		// 标记当前正在加载中...
		isLoadingNow = true
		// 同时变更
		changeBottomStateAndNotify(BottomLoading)
		val proxy = LoadMoreAdapterProxy(
			this,
			dataSyncCode.nextCode(),
			dataSyncCode,
			lastRequestBundle
		)
		attachedRecyclerView?.post {
			options.adapterCallback?.onAdapterLoadMore(proxy)
		}

		val adapterKey = this.adapterKey
		val viewModel = this.adapterViewModel
		if (adapterKey != null && viewModel != null) {
			viewModel.requestAdapterLoadMore(adapterKey, proxy)
		}
	}

	/**
	 * 请求重新加载失败部分
	 * 首次调用时会将 isLoadingNow 置为 true，防止多次重复调用
	 * 直到调用 loadCompleted / resetDataList 才会将 isLoadingMore 置为 false
	 *
	 * 调用时，会生成一个 [LoadMoreAdapterProxy] 对象，通过 [IAdapterCallback.onAdapterLoadMore] 方法
	 * 进行回调
	 *
	 * * 当调用 [LoadMoreAdapterProxy.loadOver] 时，只会将底部状态更改为 over，isLoadingNow 依旧保持 true
	 *   只有调用 [LoadMoreAdapterProxy.completed] 才会完成本次请求调用
	 *
	 */
	fun requestReload() {
		if (isLoadingNow || currentBottomState != BottomError) {
			return
		}
		isLoadingNow = true
		changeBottomStateAndNotify(BottomLoading)
		val proxy = LoadMoreAdapterProxy(
			this,
			dataSyncCode.nextCode(),
			dataSyncCode,
			lastRequestBundle
		)
		options.adapterCallback?.onAdapterReload(
			proxy
		)

		val adapterKey = this.adapterKey
		val viewModel = this.adapterViewModel
		if (adapterKey != null && viewModel != null) {
			viewModel.requestAdapterLoadMore(adapterKey, proxy)
		}
	}

	/**
	 * 请求预加载
	 * 只有在适配器没有执行过 [requestInit] 时调用 [requestPreload] 才会生效
	 * 尝试做一次预加载操作 （通过 [IAdapterCallback.onAdapterPreload] 回调实现）
	 * 如果在预加载的过程中已经执行完 [requestInit]，那么本次预加载的结果将会被忽略
	 */
	fun requestPreload() {
		if (currentBottomState != BottomNone) {
			return
		}

		val proxy = PreloadAdapterProxy(
			this,
			dataSyncCode.currentCode(),
			dataSyncCode,
			null,
			true
		)

		options.adapterCallback?.onAdapterPreload(proxy)

		val adapterKey = this.adapterKey
		val viewModel = this.adapterViewModel
		if (adapterKey != null && viewModel != null) {
			viewModel.requestAdapterPreload(adapterKey, proxy)
		}
	}


	/**
	 * 重置当前适配器数据
	 *
	 * 由 [InitAdapterProxy] 调用
	 *
	 * @param initDataList List<Any>? 数据列表
	 * @param savedBundle Bundle? 请求保存的数据集合
	 * @param isPreload Boolean 是否为预加载
	 * @param isOver Boolean 当前是否已经加载完毕
	 */
	internal fun resetDataList(
		initDataList: List<Any>? = null,
		savedBundle: Bundle? = null,
		isPreload: Boolean = false,
		isOver: Boolean = false
	) {
		if (!isPreload) {
			// 如果不是预加载，更新同步码
			// 因为预加载和首次请求有可能同时执行，作为预加载只是在请求过程中显示的
			// 数据预览，一切都以实际加载的请求为准
			dataSyncCode.nextCode()
			currentBottomState = BottomLoading
			if (isOver) {
				currentBottomState = BottomOver
			}
		}
		// 清空数据列表等与请求相关的资源数据
		dataList.clear()
		lastRequestBundle = savedBundle
		isLoadingNow = false
		adapterTempCache = null
		viewHolderHelper.clearRefreshSet()
		dataChangedMap.clear()
		if (initDataList != null) {
			dataList.addAll(filterDataList(initDataList))
		}
		notifyDataSetChanged()
	}

	/**
	 * 表示本次加载更多完成
	 * 每次加载完成后必须调用，否则自动加载功能将无法继续工作
	 * @param savedBundle Bundle? 请求保存的数据集合
	 */
	internal fun loadCompleted(savedBundle: Bundle? = null) {
		if (!isLoadingNow || currentBottomState != BottomLoading) {
			return
		}
		dataSyncCode.nextCode()
		isLoadingNow = false
		lastRequestBundle = savedBundle
	}

	/**
	 * 表示本次加载失败
	 * 底部状态会切换为 [BottomError]
	 */
	internal fun loadError() {
		if (isLoadingNow || currentBottomState != BottomLoading) {
			return
		}
		dataSyncCode.nextCode()
		isLoadingNow = false
		changeBottomStateAndNotify(BottomError)
	}

	/**
	 * 表示不再继续加载更多内容
	 * 底部状态会切换为 [BottomOver]
	 */
	internal fun loadOver() {
		dataSyncCode.nextCode()
		isLoadingNow = true
		changeBottomStateAndNotify(BottomOver)
	}


	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/28 5:04 下午 by CimZzz
	// 以下内容为:
	// 列表数据操作方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 追加列表至底部
	 * @param appendDataList List<Any> 数据列表
	 */
	fun appendList(appendDataList: List<Any>) {
		val oldSize = dataList.size
		val filterList = filterDataList(appendDataList)
		dataList.addAll(filterList)
		notifyItemRangeInserted(oldSize, filterList.size)
	}

	/**
	 * 追加列表项至底部
	 * @param data Any 列表项
	 */
	fun appendItem(data: Any) {
		// 首先需要进行数据筛选
		if (filterData(data)) {
			val oldSize = dataList.size
			dataList.add(DataWrapper(data, dataChangedMap.getCurrentCode()))
			notifyItemInserted(oldSize)
		}
	}

	/**
	 * 在指定位置添加列表项
	 * @param position Int 数据列表下标
	 * @param data Any 列表项
	 */
	fun addItemAt(position: Int, data: Any) {
		if (position < 0 || position > dataList.size) {
			// Position 位置判断
			return
		}
		if (filterData(data)) {
			dataList.add(position, DataWrapper(data, dataChangedMap.getCurrentCode()))
			notifyItemInserted(position)
		}
	}

	/**
	 * 替换列表项
	 * 如果没有通过过滤匹配，则会删除指定位置的列表项
	 * @param position Int 数据列表下标
	 * @param data Any 列表项
	 */
	fun changeItemAt(position: Int, data: Any) {
		if (filterData(data)) {
			// 过滤成功，替换列表项
			if (position < 0 || position >= dataList.size) {
				// 超出列表尺寸，不做操作
				return
			}
			dataList[position] = DataWrapper(data, dataChangedMap.getCurrentCode())
			notifyItemChanged(position)
		} else {
			// 过滤失败，删除列表项
			removeItemAt(position)
		}
	}

	/**
	 * 移动列表项
	 * @param oldPosition Int 旧位置
	 * @param newPosition Int 新位置
	 */
	fun moveItemAt(oldPosition: Int, newPosition: Int) {
		if (oldPosition == newPosition) {
			// 位置无变化
			return
		}

		if (oldPosition < 0 || oldPosition >= dataList.size) {
			// 超出列表尺寸，不做操作
			return
		}
		if (oldPosition < 0 || newPosition >= dataList.size) {
			// 新位置超出列表体积，移除旧列表项
			removeItemAt(oldPosition)
			return
		}
		val data = dataList.removeAt(oldPosition)
		dataList.add(newPosition, data)
		notifyItemMoved(oldPosition, newPosition)
	}

	/**
	 * 删除指定位置的列表项
	 * @param position Int 列表项
	 */
	fun removeItemAt(position: Int) {
		if (position < 0 || position >= dataList.size) {
			// 超出列表体积，不做操作
			return
		}

		dataList.removeAt(position)
		notifyItemRemoved(position)
	}

	/**
	 * 获取指定位置的列表项数据
	 * @param position Int 数据列表下标
	 * @return Any? 列表项
	 */
	fun getItemAt(position: Int): Any? {
		if (position >= dataList.size || position < 0) {
			// 超出列表体积，不做操作
			return null
		}

		// 拆包
		return dataList[position].data
	}

	/**
	 * 复制数据列表
	 * @param dataTransform Function1<Any, T?> 转换方法
	 * @return ArrayList<T> 复制的数据列表
	 */
	fun <T> copyDataList(dataTransform: (Any) -> T?): ArrayList<T> {
		val copiedList = ArrayList<T>()
		dataList.forEach {
			val transformedData = dataTransform(it.data!!) ?: return@forEach
			copiedList.add(transformedData)
		}
		return copiedList
	}

	/**
	 * 获取当前列表项长度
	 * @return Int 列表项长度
	 */
	fun length(): Int {
		return dataList.size
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/28 5:03 下午 by CimZzz
	// 以下内容为:
	// 适配器数据操作方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 设置适配器数据
	 * @param key String 键值
	 * @param data Any 数据
	 */
	fun setAdapterData(key: String, data: Any) {
		adapterCache[key] = data
	}

	/**
	 * 获取适配器数据
	 * @param key String 键值
	 * @return Any? 数据
	 */
	fun getAdapterData(key: String): Any? {
		return adapterCache[key]
	}

	/**
	 * 删除适配器数据
	 * @param key String 键值
	 * @return Any? 删除的数据
	 */
	fun removeAdapterData(key: String): Any? {
		return adapterCache.remove(key)
	}

	/**
	 * 清空适配器数据
	 * 注意: 当列表刷新时, 不会自动清空适配器数据, 如果有需要, 应该主动调用该方法
	 */
	fun clearAdapterData() {
		adapterCache.clear()
	}

	/**
	 * 获取临时适配器数据
	 * @param key String 键值
	 * @return Any? 数据
	 */
	fun getAdapterTempData(key: String): Any? {
		return adapterTempCache?.get(key)
	}

	/**
	 * 保存临时适配器数据
	 * @param key String 键值
	 * @param data Any 数据
	 */
	fun saveAdapterTempData(key: String, data: Any) {
		val tempCache = if (adapterTempCache == null) {
			val cache = HashMap<String, Any>()
			adapterTempCache = cache
			cache
		} else {
			adapterTempCache
		}
		tempCache?.put(key, data)
	}

	/**
	 * 移除临时适配器数据
	 * @param key String 键值
	 */
	fun removeAdapterTempData(key: String) {
		adapterTempCache?.remove(key)
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/12/28 5:03 下午 by CimZzz
	// 以下内容为:
	// 列表状态操作方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 手动发布滑动状态变化
	 * @param state Int 滑动状态
	 */
	fun dispatchScrollState(@ScrollState state: Int) {
		viewHolderHelper.changeScrollState(state)
	}


	/**
	 * 数据发生变化，会刷新目前显示的全部 ViewHolder
	 * @param key String 键值
	 * @param data Any? 数据
	 */
	fun notifyDataChanged(key: String, data: Any?) {
		val recyclerView = attachedRecyclerView ?: return
		dataChangedMap.dataChanged(key = key, data = data, dataList.size + checkBottomView())
		recyclerView.forEach {
			val viewHolder = recyclerView.getChildViewHolder(it) as BaseViewHolder<*>
			viewHolderHelper.handleDataChanged(viewHolder, true)
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/1/26 下午2:05 by CimZzz
	// 以下内容为:
	// 内部类
	///////////////////////////////////////////////////////////////////////////

	/**
	 * Adapter 配置类
	 */
	data class Options(
		/**
		 * 生命周期循环
		 */
		val lifecycle: WeakReference<LifecycleOwner>? = null,
		/**
		 * 底部加载中的布局 Id
		 */
		val bottomLoadingLayoutId: Int? = null,
		/**
		 * 底部加载失败的布局 Id
		 */
		val bottomErrorLayoutId: Int? = null,
		/**
		 * 底部加载失败点击刷新的 View Id
		 */
		val bottomErrorClickLayoutId: Int? = null,
		/**
		 * 底部加载完成的布局 Id
		 */
		val bottomOverLayoutId: Int? = null,
		/**
		 * 内部数据缓存池最大尺寸
		 */
		val maxCacheCount: Int = 300,

		/**
		 * 适配器加载策略
		 */
		val adapterLoadStrategy: IAdapterLoadStrategy? = null,

		/**
		 * 适配器滑动策略
		 */
		val adapterScrollStrategy: IAdapterScrollStrategy? = null,
		/**
		 * 适配器回调
		 */
		val adapterCallback: IAdapterCallback? = null,

		/**
		 * 数据匹配器列表
		 */
		val dataMatcherSet: Set<BaseDataMatcher<*>>
	) {
		/**
		 * 合并所有 BaseDataMatcher，生成一个新的适配器配置类
		 * @param matcherArray Array<BaseDataMatcher<*>> BaseDataMatcher 数组
		 * @return Options 新的 Options
		 */
		fun mergeDataMatcher(matcherArray: Array<BaseDataMatcher<*>>): Options {
			val matcherSet = HashSet<BaseDataMatcher<*>>()
			matcherSet.addAll(matcherArray)
			dataMatcherSet.forEach {
				if (matcherSet.contains(it)) {
					return@forEach
				}
				matcherSet.add(it)
			}

			return copy(dataMatcherSet = matcherSet)
		}
	}

	/**
	 * 数据包装器
	 */
	internal data class DataWrapper<T>(
		/**
		 * 数据
		 */
		var data: T,

		/**
		 * 数据码变化码
		 */
		var dataChangedCode: Int
	) {
		/**
		 * 缓存数据
		 */
		var cachedMap: MutableMap<String, Any>? = null
	}

	/**
	 * View Holder 代理类
	 * @param T 数据类型
	 */
	abstract class BaseViewHolderProxy<T> {

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/29 7:29 下午 by CimZzz
		// 以下内容为:
		// 内部使用方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 创建内部 ViewHolder
		 * @param layoutInflater LayoutInflater 布局填充器
		 * @param parent ViewGroup 父布局
		 * @return InnerViewHolder 生成内部 ViewHolder
		 */
		internal fun createViewHolder(layoutInflater: LayoutInflater, parent: ViewGroup): InnerViewHolder {
			return InnerViewHolder(this, onCreateView(layoutInflater, parent))
		}

		/**
		 * 附着布局
		 */
		internal fun attach() {
			onAttach()
		}

		/**
		 * 分离布局
		 */
		internal fun detach() {
			onDetach()
		}

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/29 7:29 下午 by CimZzz
		// 以下内容为:
		// 子类实现方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 生成子视图
		 * @param layoutInflater LayoutInflater 布局填充器
		 * @param parent ViewGroup 父布局
		 * @return View 生成的子视图
		 */
		protected abstract fun onCreateView(layoutInflater: LayoutInflater, parent: ViewGroup): View

		/**
		 * 附着布局回调方法
		 */
		protected open fun onAttach() {

		}

		/**
		 * 分离布局回调方法
		 */
		protected open fun onDetach() {

		}
	}

	/**
	 * 内部
	 */
	internal class InnerViewHolder(
		private val proxy: BaseViewHolderProxy<*>,
		itemView: View
	) : RecyclerView.ViewHolder(itemView)

	/**
	 * ViewHolder 基类
	 */
	abstract class BaseViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView),
		DataChangedCacheMap.DataChangedObserver {

		/**
		 * Attach 同步 Code
		 */
		internal val attachSyncCode = SyncCode()

		/**
		 * 判断当前 ViewHolder 是否正在使用
		 */
		private var isUsing = true

		/**
		 * 内部 ViewHolder Helper
		 */
		var helper: WeakReference<ViewHolderHelper>? = null

		/**
		 * 内部生命周期工具
		 */
		private var innerLifecycle: TinyLifecycle? = null

		/**
		 * 数据包装器
		 */
		internal var dataWrapper: DataWrapper<T>? = null

		/**
		 * 锁定刷新状态
		 */
		internal var isLockRefresh: Boolean = false

		/**
		 * 锁定过程中需要刷新
		 */
		internal var needRefreshDuringLocked: Boolean = false

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/28 5:50 下午 by CimZzz
		// 以下内容为:
		// ViewHolder 生命周期方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 初始化方法
		 * 由 [UniverseAdapter.onCreateViewHolder] 调用
		 */
		internal fun init() {
			onInit()
		}

		/**
		 * 初始化回调，子类可重写实现初始化操作
		 */
		protected open fun onInit() {

		}

		/**
		 * 当 ViewHolder Attach 时调用
		 * 由 [UniverseAdapter.onViewAttachedToWindow] 调用
		 */
		internal fun attach() {
			helper?.get()?.handleDataChanged(this, true)
			onAttach()
		}

		/**
		 * Attach 时回调
		 * 子类重写该方法进行 Attach 时的一些操作
		 */
		protected open fun onAttach() {

		}

		/**
		 * 当 ViewHolder Detach 时调用
		 * 由 [UniverseAdapter.onViewDetachedFromWindow] 调用
		 */
		internal fun detach() {
			onDetach()
		}

		/**
		 * Detach 时回调，子类可以重写该方法进行 Detach 时的一些操作
		 */
		protected open fun onDetach() {

		}

		/**
		 * 当前 ViewHolder Recycled 时调用
		 * 由 [UniverseAdapter.onViewRecycled] 调用
		 */
		internal fun recycled() {
			isUsing = false
			this.dataWrapper = null
			attachSyncCode.nextCode()
			innerLifecycle?.setLifeState(Lifecycle.State.DESTROYED)
			innerLifecycle = null
			onRecycled()
		}

		/**
		 * Recycled 时回调，子类可以重写该方法进行 Recycled 时的一些操作
		 */
		protected open fun onRecycled() {

		}

		/**
		 * 绑定数据
		 * 由 [UniverseAdapter.onBindViewHolder] 方法调用
		 *
		 * @param data DataWrapper<*> 数据包装器
		 * @param helper ViewHolderHelper ViewHolder 帮助类
		 */
		internal fun bindData(data: DataWrapper<*>, helper: ViewHolderHelper) {
			isUsing = true
			this.dataWrapper = data as DataWrapper<T>
			this.helper = WeakReference(helper)
			helper.handleDataChanged(this, false)
			onBindData(data.data, helper)
		}

		/**
		 * 绑定数据时回调方法，子类必须重写该方法进行数据绑定
		 * @param data T 数据
		 * @param helper ViewHolderHelper ViewHolder 帮助类
		 */
		protected abstract fun onBindData(data: T, helper: ViewHolderHelper)

		/**
		 * 调用滑动状态变更回调
		 * 当滑动状态变化时，触发此方法。
		 * 由 [ViewHolderHelper.changeScrollState] 调用
		 */
		internal fun callScrollStateChanged() {
			val existHelper = helper?.get() ?: return
			val existData = getData() ?: return
			onScrollStateChanged(existData, existHelper)
		}

		/**
		 * 滑动状态变化回调，子类可以重写该方法处理滑动速度变化的一些方法
		 * @param data T 数据
		 * @param helper ViewHolderHelper ViewHolder 帮助类
		 */
		protected open fun onScrollStateChanged(data: T, helper: ViewHolderHelper) {

		}

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/28 5:53 下午 by CimZzz
		// 以下内容为:
		// 刷新锁定 & 解锁方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 锁定 ViewHolder 自行刷新
		 */
		internal fun lockRefresh() {
			isLockRefresh = true
			needRefreshDuringLocked = false
		}

		/**
		 * 解锁 ViewHolder 刷新
		 */
		internal fun unlockRefresh() {
			isLockRefresh = false
			if (needRefreshDuringLocked) {
				refreshUI()
			}
		}

		/**
		 * 解锁 ViewHolder 刷新
		 */
		internal fun unlockRefreshAndNoRefresh() {
			isLockRefresh = false
			needRefreshDuringLocked = false
		}

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/12/28 5:55 下午 by CimZzz
		// 以下内容为:
		// 实现 DataChangedObserver 的方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 数据同步码变化
		 * @param code Int 数据同步码
		 */
		final override fun onDataChangeCode(code: Int) {
			this.dataWrapper?.dataChangedCode = code
		}


		/**
		 * 获取数据变化码
		 * @return Int 数据同步码
		 */
		final override fun getDataChangeCode(): Int = this.dataWrapper?.dataChangedCode ?: -1

		/**
		 * 处理数据变化回调
		 * @param key String
		 * @param data Any?
		 */
		override fun onDataChanged(key: String, data: Any?) {

		}

		///////////////////////////////////////////////////////////////////////////
		// 代码分割线 on 2021/3/16 下午1:35 by CimZzz
		// 以下内容为:
		// 子类可使用方法
		///////////////////////////////////////////////////////////////////////////

		/**
		 * 获取数据
		 * @return T? 数据
		 */
		protected fun getData(): T? {
			return this.dataWrapper?.data
		}

		/**
		 * 更新数据
		 * @param data T 新的数据
		 */
		protected fun updateData(data: T) {
			this.dataWrapper?.data = data
			refreshUI()
		}

		/**
		 * 刷新当前 UI
		 */
		protected fun refreshUI() {
			if (isLockRefresh) {
				// 如果当前处于刷新锁定状态，记录当前需要刷新，等刷新锁定解锁后调用刷新
				needRefreshDuringLocked = true
				return
			}
			val helper = this.helper?.get() ?: return
			helper.notifyUpdate(adapterPosition)
		}

		/**
		 * 通知数据变化
		 * @param key String 键值
		 * @param data Any? 数据
		 */
		protected fun notifyDataChanged(key: String, data: Any?) {
			val helper = this.helper?.get() ?: return
			helper.notifyDataChanged(key, data)
		}

		/**
		 * 发送适配器命令
		 * @param data Any? 伴随的数据
		 */
		fun sendCommand(data: Any? = null) {
			if (!isUsing) {
				return
			}
			helper?.get()?.sendCommand(
				adapterPosition, this, getData(), data, 0
			)
		}

		/**
		 * 发送场景适配器命令
		 * @param scene Int 场景码
		 * @param data Any? 伴随的数据
		 */
		fun sendSceneCommand(scene: Int, data: Any? = null) {
			if (!isUsing) {
				return
			}
			helper?.get()?.sendCommand(
				adapterPosition, this, getData(), data, scene
			)
		}

		/**
		 * 获取适配器数据
		 * @param key String 键值
		 * @return T? 适配器数据
		 */
		fun <T> getAdapterData(key: String): T? {
			if (!isUsing) {
				return null
			}
			return helper?.get()?.getAdapterData(key) as? T
		}

		/**
		 * 保存适配器数据
		 * @param key String 键值
		 * @param data Any 数据
		 */
		fun saveAdapterData(key: String, data: Any) {
			if (!isUsing) {
				return
			}
			helper?.get()?.saveAdapterData(key, data)
		}

		/**
		 * 获取临时适配器数据
		 * @param key String 键值
		 * @return T? 适配器数据
		 */
		fun <T> getAdapterTempData(key: String): T? {
			if (!isUsing) {
				return null
			}
			return helper?.get()?.getAdapterTempData(key) as? T
		}

		/**
		 * 获取临时适配器数据
		 * @param key String 键值
		 * @param generator Function0<T> 如果键值不存在，则会通过该回调生成一个初始值
		 * @return T 适配器数据
		 */
		fun <T : Any> getAdapterTempData(key: String, generator: () -> T): T {
			if (!isUsing) {
				return generator()
			}
			val result = getAdapterTempData<T>(key)
			if (result != null) {
				return result
			}
			val newItem = generator()
			saveAdapterTempData(key, newItem)
			return newItem
		}

		/**
		 * 保存临时适配器数据
		 * @param key String 键值
		 * @param data Any 数据
		 */
		fun saveAdapterTempData(key: String, data: Any) {
			if (!isUsing) {
				return
			}
			helper?.get()?.saveAdapterTempData(key, data)
		}

		/**
		 * 移除临时适配器数据
		 * @param key String 键值
		 */
		fun removeAdapterTempData(key: String) {
			if (!isUsing) {
				return
			}
			helper?.get()?.removeAdapterTempData(key)
		}

		/**
		 * 获取 ViewHolder 缓存数据
		 * @param key String 键值
		 * @return T? 数据
		 */
		fun <T> getCachedData(key: String): T? {
			if (!isUsing) {
				return null
			}
			val cachedMap = this.dataWrapper?.cachedMap ?: return null
			return cachedMap[key] as? T
		}

		/**
		 * 保存 ViewHolder 缓存数据
		 * @param key String 键值
		 * @param data Any 数据
		 */
		fun saveCacheData(key: String, data: Any) {
			if (!isUsing) {
				return
			}
			val cacheKey = this.dataWrapper ?: return
			val cacheMap = cacheKey.cachedMap ?: HashMap<String, Any>().let {
				cacheKey.cachedMap = it
				it
			}
			cacheMap[key] = data
		}

		/**
		 * 获取 View Holder 生命周期循环
		 * @return TinyLifecycle? View Holder 生命周期循环
		 */
		fun getTinyLifecycle(): TinyLifecycle? {
			if (!isUsing) {
				return null
			}

			if (innerLifecycle == null) {
				innerLifecycle = TinyLifecycle()
			}
			return innerLifecycle
		}

		/**
		 * 找到 ViewHolder 内部的 ViewModel
		 * @param key String? ViewModel 键值
		 * @return T? View Model
		 */
		inline fun <reified T : ViewModel> findViewModel(key: String? = null): T? {
			val lifeCycle = getTinyLifecycle() ?: return null
			return lifeCycle.findViewModel(key)
		}

		/**
		 * 获取适配器的生命周期循环
		 * @return LifecycleOwner? 适配器生命周期循环
		 */
		fun getAdapterLifecycle(): LifecycleOwner? {
			if (!isUsing) {
				return null
			}

			return helper?.get()?.getAdapterLifecycle()
		}
	}


	/**
	 * 适配器状态
	 */
	class OuterState {
		/**
		 * 当前适配器滑动状态
		 */
		internal var scrollState: Int = ScrollStateIdle
		fun getScrollState() = scrollState
	}

	/**
	 * ViewHolder 帮助类
	 */
	inner class ViewHolderHelper {
		/**
		 * 延迟刷新集合
		 */
		internal var delayRefreshSet: HashSet<Int>? = null

		/**
		 * 获取适配器状态
		 * @return OuterState 适配器状态
		 */
		fun getOutState() = outerState

		/**
		 * 处理 Holder 数据变化
		 * @param holder BaseViewHolder<*> ViewHolder
		 * @param canRefresh Boolean 是否允许刷新
		 */
		internal fun handleDataChanged(holder: BaseViewHolder<*>, canRefresh: Boolean) {
			holder.lockRefresh()
			dataChangedMap.handleDataChanged(holder)
			if (canRefresh) {
				holder.unlockRefresh()
			} else {
				holder.unlockRefreshAndNoRefresh()
			}
		}

		/**
		 * 获取适配器数据
		 * @param key String 键值
		 * @return Any? 数据
		 */
		internal fun getAdapterData(key: String): Any? {
			return adapterCache[key]
		}

		/**
		 * 保存适配器数据
		 * @param key String 键值
		 * @param data Any 数据
		 */
		internal fun saveAdapterData(key: String, data: Any) {
			adapterCache[key] = data
		}

		/**
		 * 获取临时适配器数据
		 * @param key String 键值
		 * @return Any? 数据
		 */
		internal fun getAdapterTempData(key: String): Any? {
			return this@UniverseAdapter.getAdapterTempData(key)
		}

		/**
		 * 保存临时适配器数据
		 * @param key String 键值
		 * @param data Any 数据
		 */
		internal fun saveAdapterTempData(key: String, data: Any) {
			this@UniverseAdapter.saveAdapterTempData(key, data)
		}

		/**
		 * 移除临时适配器数据
		 * @param key String 键值
		 */
		internal fun removeAdapterTempData(key: String) {
			this@UniverseAdapter.removeAdapterTempData(key)
		}

		/**
		 * 获取适配器的生命周期
		 * @return Lifecycle? 适配器的生命周期循环
		 */
		internal fun getAdapterLifecycle(): LifecycleOwner? {
			if (attachedRecyclerView == null) {
				return null
			}
			return options.lifecycle?.get()
		}

		/**
		 * 切换滑动状态
		 * @param afterState Int 更新后的滑动状态
		 */
		internal fun changeScrollState(afterState: Int) {
			if (outerState.getScrollState() == afterState) {
				/// 滚动状态无变化，不做处理
				return
			}

			if (afterState !in (ScrollStateFast..ScrollStateIdle)) {
				throw RuntimeException("非法的滚动状态变更")
			}

			outerState.scrollState = afterState

			val collections = (0 until (attachedRecyclerView?.childCount
				?: 0)).mapNotNull { attachedRecyclerView?.getChildAt(it) }.mapNotNull {
				val viewHolder = attachedRecyclerView?.getChildViewHolder(it) as? BaseViewHolder<*>
					?: return@mapNotNull null
				if (viewHolderHelper.checkInDelayRefreshSet(viewHolder.adapterPosition)) {
					return@mapNotNull null
				}
				viewHolder
			}
			when (afterState) {
				ScrollStateSlow -> {
					collections.forEach { it.callScrollStateChanged() }
				}
				ScrollStateFast -> {
					collections.forEach { it.callScrollStateChanged() }
				}
				ScrollStateIdle -> {
					collections.forEach {
						it.callScrollStateChanged()
					}
					viewHolderHelper.delayRefreshSet?.forEach {
						notifyItemChanged(it)
					}
					viewHolderHelper.clearRefreshSet()
				}
			}
		}

		/**
		 * 发送适配器命令
		 * @param index Int 发出命令的 ViewHolder 下标
		 * @param viewHolder BaseViewHolder<*> 发出命令的 ViewHolder
		 * @param data Any? 发送命令的 ViewHolder 所绑定的数据
		 * @param carryData Any? 适配器命令伴随数据
		 * @param scene Int 场景码
		 */
		internal fun sendCommand(
			index: Int,
			viewHolder: BaseViewHolder<*>,
			data: Any?,
			carryData: Any?,
			scene: Int
		) {
			if (index == -1) {
				// 过滤, 当 item 从列表中移除后, 如果展示过渡动画, 则 index 为 -1
				return
			}
			val command = AdapterCommand(
				index,
				viewHolder::class.java,
				data,
				carryData,
				scene
			)

			options.adapterCallback?.onAdapterCommand(command)

			val viewModel = adapterViewModel
			val adapterKey = adapterKey
			if (adapterKey != null && viewModel != null) {
				viewModel.onAdapterCommand(adapterKey, command)
			}
		}

		/**
		 * 通知适配器列表项发生变化
		 * @param position Int 下标
		 */
		internal fun notifyUpdate(position: Int) {
			if (getOutState().scrollState == ScrollStateIdle) {
				// 如果当前处于静止状态，更新列表项
				notifyItemChanged(position)
			} else {
				// 否则添加至延迟刷新集合中，等下次滑动静止时执行刷新
				// 这么做的原因是在列表高速滑动过程中，一直不断执行 Layout，如果在 Layout 过程中通知适配器
				// 某一列表项需要更新，会引发崩溃
				val delaySet = this.delayRefreshSet ?: HashSet<Int>().let {
					this.delayRefreshSet = it
					it
				}
				delaySet.add(position)
			}
		}

		/**
		 * 回收延迟刷新集合
		 */
		internal fun clearRefreshSet() {
			this.delayRefreshSet = null
		}

		/**
		 * 检查是否在延迟刷新集合中
		 * @param position Int 下标
		 * @return Boolean 如果存在返回 true
		 */
		internal fun checkInDelayRefreshSet(position: Int): Boolean {
			return this.delayRefreshSet?.contains(position) ?: false
		}

		/**
		 * ViewHolder 通知数据变化
		 * @param key String 键值
		 * @param data Any? 数据
		 */
		internal fun notifyDataChanged(key: String, data: Any?) {
			this@UniverseAdapter.notifyDataChanged(key, data)
		}

	}

	/**
	 * 列表底部状态 ViewHolder
	 */
	class BottomViewHolder(
		private val rootView: SwitchView,
		// 适配器配置信息
		private val options: Options
	) : BaseViewHolder<Int>(rootView) {
		override fun onBindData(data: Int, helper: ViewHolderHelper) {
			when (data) {
				BottomLoading -> {
					rootView.show(options.bottomLoadingLayoutId ?: return)
				}
				BottomError -> {
					rootView.show(options.bottomErrorLayoutId ?: return)
				}
				BottomOver -> {
					rootView.show(options.bottomOverLayoutId ?: return)
				}
			}
		}
	}

	/**
	 * 数据匹配项
	 */
	internal class DataMatchCase<T>(
		/**
		 * ViewHolder 类型
		 */
		val itemType: Int,

		/**
		 * ViewHolder 工厂
		 */
		val viewHolderFactory: IViewHolderFactory<T, *>
	)

	/**
	 * 多数据匹配项
	 */
	internal class MultiDataMatchCase<T>(
		/**
		 * ViewHolder 类型
		 */
		val itemType: Int,
		/**
		 * ViewHolder 工厂
		 */
		val viewHolderFactory: IViewHolderFactory<*, *>,
		/**
		 * 数据项匹配方法回调
		 */
		val matcherCallback: (T) -> Boolean
	) {

		/**
		 * 判断数据是否匹配
		 * @param data Any 待匹配数据
		 * @return Boolean 如果匹配成功返回 true
		 */
		fun isMatch(data: Any): Boolean {
			return matcherCallback(data as T)
		}
	}

	/**
	 * 数据匹配器基类
	 */
	abstract class BaseDataMatcher<T> internal constructor(
		/**
		 * 数据类
		 */
		val dataCls: Class<T>,

		/**
		 * ViewHolder 类
		 */
		val viewHolderCls: Class<out BaseViewHolder<*>>
	)

	/**
	 * 普通数据匹配器
	 * 数据类型和 ViewHolder 类型做匹配
	 */
	class DataMatcher<T>(
		dataCls: Class<T>,
		viewHolderCls: Class<out BaseViewHolder<T>>
	) : BaseDataMatcher<T>(dataCls, viewHolderCls) {
		override fun equals(other: Any?): Boolean {
			return other is DataMatcher<*> && other.dataCls == dataCls
		}

		override fun hashCode(): Int {
			return dataCls.hashCode()
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// Add by CimZzz on 2021/3/15 上午9:38
	// 扩展数据匹配器，支持同一数据类型，根据内部字段不同返回不同的 ViewHolder 类型
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 扩展数据匹配器，支持同一数据类型，根据内部字段不同返回不同的 ViewHolder 类型
	 */
	class ExtendDataMatcher<T>(
		dataCls: Class<T>,
		viewHolderCls: Class<out BaseViewHolder<T>>,
		/**
		 * 匹配方法
		 */
		val matchCallback: (T) -> Boolean
	) : BaseDataMatcher<T>(dataCls, viewHolderCls) {


		/**
		 * 判断数据是否匹配
		 * @param data Any 待匹配数据
		 * @return Boolean 如果匹配成功返回 true
		 */
		fun isMatch(data: Any): Boolean {
			return matchCallback(data as T)
		}

		/**
		 * 生成多数据匹配项
		 * @param itemType Int ViewHolder 类型
		 * @param viewHolderFactory IViewHolderFactory<*, *> ViewHolder 工厂
		 * @return MultiDataMatchCase<T> 多数据匹配项
		 */
		internal fun generateMultiDataMatchCase(
			itemType: Int,
			viewHolderFactory: IViewHolderFactory<*, *>
		): MultiDataMatchCase<T> {
			return MultiDataMatchCase(
				itemType, viewHolderFactory, matchCallback
			)
		}

		override fun equals(other: Any?): Boolean {
			return other is ExtendDataMatcher<*> && other.dataCls == dataCls && other.viewHolderCls == viewHolderCls && other.matchCallback == matchCallback
		}

		override fun hashCode(): Int {
			return dataCls.hashCode()
		}
	}

	/**
	 * 继承扩展数据匹配器，可以使用基类 ViewHolder 表示子类数据类型
	 * 注意，使用的时候需要注意，确保子类和基类关系，适配器内部不会针对此关系进行校验
	 */
	class InheritDataMatcher<T>(
		dataCls: Class<T>,
		viewHolderCls: Class<out BaseViewHolder<*>>,
	) : BaseDataMatcher<T>(dataCls, viewHolderCls) {
		override fun equals(other: Any?): Boolean {
			return other is InheritDataMatcher<*> && other.dataCls == dataCls
		}

		override fun hashCode(): Int {
			return dataCls.hashCode()
		}
	}

	class TempDataMatcher<T> (
		dataCls: Class<T>,

	)
}